vulkan: Pass color rects in instance data
authorBenjamin Otte <otte@redhat.com>
Sun, 18 Dec 2016 05:54:48 +0000 (06:54 +0100)
committerBenjamin Otte <otte@redhat.com>
Tue, 20 Dec 2016 17:01:11 +0000 (18:01 +0100)
This way, we don't need push constants or per-vertex data, we can render
colored rectangles completely via instance data.

gsk/gskvulkancolorpipeline.c
gsk/gskvulkancolorpipelineprivate.h
gsk/gskvulkanrenderpass.c
gsk/resources/vulkan/color.frag.glsl
gsk/resources/vulkan/color.frag.spv
gsk/resources/vulkan/color.vert.glsl
gsk/resources/vulkan/color.vert.spv

index 6702537896966d7bd4a7f98aedba2f708d6a0156..ab6c3e581f99d9d19116a05d33f6f0549487a771 100644 (file)
@@ -7,12 +7,12 @@ struct _GskVulkanColorPipeline
   GObject parent_instance;
 };
 
-typedef struct _GskVulkanVertex GskVulkanVertex;
+typedef struct _GskVulkanColorInstance GskVulkanColorInstance;
 
-struct _GskVulkanVertex
+struct _GskVulkanColorInstance
 {
-  float x;
-  float y;
+  float rect[4];
+  float color[4];
 };
 
 G_DEFINE_TYPE (GskVulkanColorPipeline, gsk_vulkan_color_pipeline, GSK_TYPE_VULKAN_PIPELINE)
@@ -23,16 +23,22 @@ gsk_vulkan_color_pipeline_get_input_state_create_info (GskVulkanPipeline *self)
   static const VkVertexInputBindingDescription vertexBindingDescriptions[] = {
       {
           .binding = 0,
-          .stride = sizeof (GskVulkanVertex),
-          .inputRate = VK_VERTEX_INPUT_RATE_VERTEX
+          .stride = sizeof (GskVulkanColorInstance),
+          .inputRate = VK_VERTEX_INPUT_RATE_INSTANCE
       }
   };
   static const VkVertexInputAttributeDescription vertexInputAttributeDescription[] = {
       {
           .location = 0,
           .binding = 0,
-          .format = VK_FORMAT_R32G32_SFLOAT,
+          .format = VK_FORMAT_R32G32B32A32_SFLOAT,
           .offset = 0,
+      },
+      {
+          .location = 1,
+          .binding = 0,
+          .format = VK_FORMAT_R32G32B32A32_SFLOAT,
+          .offset = G_STRUCT_OFFSET (GskVulkanColorInstance, color),
       }
   };
   static const VkPipelineVertexInputStateCreateInfo info = {
@@ -80,22 +86,25 @@ gsk_vulkan_color_pipeline_new (GskVulkanPipelineLayout *layout,
 gsize
 gsk_vulkan_color_pipeline_count_vertex_data (GskVulkanColorPipeline *pipeline)
 {
-  return sizeof (GskVulkanVertex) * 6;
+  return sizeof (GskVulkanColorInstance);
 }
 
 void
 gsk_vulkan_color_pipeline_collect_vertex_data (GskVulkanColorPipeline *pipeline,
                                                guchar                 *data,
-                                               const graphene_rect_t  *rect)
+                                               const graphene_rect_t  *rect,
+                                               const GdkRGBA          *color)
 {
-  GskVulkanVertex *vertices = (GskVulkanVertex *) data;
-
-  vertices[0] = (GskVulkanVertex) { rect->origin.x,                    rect->origin.y };
-  vertices[1] = (GskVulkanVertex) { rect->origin.x + rect->size.width, rect->origin.y };
-  vertices[2] = (GskVulkanVertex) { rect->origin.x,                    rect->origin.y + rect->size.height };
-  vertices[3] = (GskVulkanVertex) { rect->origin.x,                    rect->origin.y + rect->size.height };
-  vertices[4] = (GskVulkanVertex) { rect->origin.x + rect->size.width, rect->origin.y };
-  vertices[5] = (GskVulkanVertex) { rect->origin.x + rect->size.width, rect->origin.y + rect->size.height };
+  GskVulkanColorInstance *instance = (GskVulkanColorInstance *) data;
+
+  instance->rect[0] = rect->origin.x;
+  instance->rect[1] = rect->origin.y;
+  instance->rect[2] = rect->size.width;
+  instance->rect[3] = rect->size.height;
+  instance->color[0] = pow (color->red, 2.2);
+  instance->color[1] = pow (color->green, 2.2);
+  instance->color[2] = pow (color->blue, 2.2);
+  instance->color[3] = color->alpha;
 }
 
 gsize
@@ -105,8 +114,8 @@ gsk_vulkan_color_pipeline_draw (GskVulkanColorPipeline *pipeline,
                                 gsize                   n_commands)
 {
   vkCmdDraw (command_buffer,
-             n_commands * 6, 1,
-             offset, 0);
+             6, n_commands,
+             0, offset);
 
-  return n_commands * 6;
+  return n_commands;
 }
index 4fbc22a44f1cf535609aa74e74538aed91535bf4..07e63827c899ff0fabbadcdabb714ab511e1417c 100644 (file)
@@ -20,7 +20,8 @@ GskVulkanPipeline *     gsk_vulkan_color_pipeline_new                   (GskVulk
 gsize                   gsk_vulkan_color_pipeline_count_vertex_data     (GskVulkanColorPipeline         *pipeline);
 void                    gsk_vulkan_color_pipeline_collect_vertex_data   (GskVulkanColorPipeline         *pipeline,
                                                                          guchar                         *data,
-                                                                         const graphene_rect_t          *rect);
+                                                                         const graphene_rect_t          *rect,
+                                                                         const GdkRGBA                  *color);
 gsize                   gsk_vulkan_color_pipeline_draw                  (GskVulkanColorPipeline         *pipeline,
                                                                          VkCommandBuffer                 command_buffer,
                                                                          gsize                           offset,
index 337b6adbfff3621a4f29cd0a50ba6cec42b2504e..fed4e7caeb442f94c26f6f4fe75cf30c0a193a42 100644 (file)
@@ -333,7 +333,8 @@ gsk_vulkan_render_pass_collect_vertex_data (GskVulkanRenderPass *self,
             op->render.vertex_offset = offset + n_bytes;
             gsk_vulkan_color_pipeline_collect_vertex_data (GSK_VULKAN_COLOR_PIPELINE (op->render.pipeline),
                                                            data + n_bytes + offset,
-                                                           &bounds);
+                                                           &bounds,
+                                                           gsk_color_node_peek_color (op->render.node));
             n_bytes += op->render.vertex_count;
           }
           break;
index fba9e47120038428e0ca7f3c057f34e5db58414b..cbac7ed96137421451078a923cfdb98f8fbc66c4 100644 (file)
@@ -1,6 +1,6 @@
 #version 420 core
 
-layout(set = 0, binding = 0) uniform sampler2D inTexture;
+layout(location = 0) in vec4 inColor;
 
 layout(push_constant) uniform PushConstants {
     mat4 mvp;
@@ -11,5 +11,5 @@ layout(location = 0) out vec4 color;
 
 void main()
 {
-    color = push.color;
+    color = inColor;
 }
index beee876b1766f81a3300a7044cc4aefc323d0e0c..2865771377a09b53eb2b06abe5bfee8ad8e3d5af 100644 (file)
Binary files a/gsk/resources/vulkan/color.frag.spv and b/gsk/resources/vulkan/color.frag.spv differ
index 849d5cd51701735e600ef0fe8b487c20f21217f9..78bbfe12831c725318d3e31936f369181c8e0595 100644 (file)
@@ -1,15 +1,27 @@
 #version 420 core
 
-layout(location = 0) in vec2 inPosition;
+layout(location = 0) in vec4 inRect;
+layout(location = 1) in vec4 inColor;
 
 layout(push_constant) uniform PushConstants {
     mat4 mvp;
 } push;
 
+layout(location = 0) out vec4 outColor;
+
 out gl_PerVertex {
   vec4 gl_Position;
 };
 
+vec2 offsets[6] = { vec2(0.0, 0.0),
+                    vec2(1.0, 0.0),
+                    vec2(0.0, 1.0),
+                    vec2(0.0, 1.0),
+                    vec2(1.0, 0.0),
+                    vec2(1.0, 1.0) };
+
 void main() {
-  gl_Position = push.mvp * vec4 (inPosition, 0.0, 1.0);
+  vec2 pos = inRect.xy + inRect.zw * offsets[gl_VertexIndex];
+  gl_Position = push.mvp * vec4 (pos, 0.0, 1.0);
+  outColor = inColor;
 }
index a7ca96a42546d99e7319d7539ab79b1befc0fc84..f4a8791bd700d26a4f3f2bbd69d5f0c99d8e31a5 100644 (file)
Binary files a/gsk/resources/vulkan/color.vert.spv and b/gsk/resources/vulkan/color.vert.spv differ